<template>
	<view class="kui-switch kui-flex kui-items-center" :id="rootState.id" :style="rootStyle" @click="onClick">
		<view class="kui-switch-button kui-flex kui-justify-center kui-items-center" :class="[buttonState.status]" :style="buttonStyle">
			<kui-animation name="rotate-center" :duration="1" runing infinite v-if="rootState.loading">
				<kui-icons :size="iconState.size" :color="iconState.color" type="spinner6"></kui-icons>
			</kui-animation>
			<view class="open-text" v-if="activeText && modelValue">
				<kui-text :size="textState.size" :color="textState.color">{{ activeText }}</kui-text>
			</view>
			<view class="close-text" v-if="inactiveText && !modelValue">
				<kui-text :size="textState.size" :color="textState.color">{{ inactiveText }}</kui-text>
			</view>
		</view>
	</view>
</template>

<script lang="ts">
	import {
		reactive,
		getCurrentInstance,
		CSSProperties,
		watch,
		computed,
		defineComponent,
		SetupContext,
		nextTick
	} from 'vue';
	
	import SwitchProps from './props';
	
	const name = 'kui-switch';
	
	export default defineComponent({
		name,
		props: SwitchProps,
		emits: ['update:modelValue', 'change'],
		setup(props, { emit }) {
			// 随机生成元素ID
			const elId = `kUI_${Math.ceil(new Date().getTime() * 10e5).toString(36)}`;
			
			const {
				proxy
			}: any = getCurrentInstance();
			const theme = proxy.$theme;
			
			const isActive = computed(() => props.modelValue === props.activeValue);
			
			const rootState = reactive({
				disabled: props.disabled,
				loading: props.loading,
				isDark: props.mode === 'dark',
				id: elId
			});
			
			const buttonState = reactive({
				status: isActive.value ? 'open' : 'close'
			});
			
			const iconState = reactive({
				size: 20,
				color: ''
			});
			
			const textState = reactive({
				color: theme.colors[props.mode]['grey'][0],
				size: `${theme.size.fonts.sm}rpx`
			});
			
			const activeIconColorMap = theme.colors[props.mode][props.iconColor] ? theme.colors[props.mode][props.iconColor] : uni.kviewUIColor.generate(props.iconColor, {dark: rootState.isDark, list: true});
			const inactiveColorMap = theme.colors[props.mode][props.inactiveColor];
						
			const changeStatus = () => {
				iconState.color = isActive.value ? activeIconColorMap[5] : inactiveColorMap[4];
			}
			
			changeStatus();
			
			const rootStyle = computed(() => {
				const style: CSSProperties = reactive({});
				
				style.width = '72rpx';
				style.height = '42rpx';
				const activeColorMap = theme.colors[props.mode][props.activeColor] ? theme.colors[props.mode][props.activeColor] : uni.kviewUIColor.generate(props.activeColor, {dark: rootState.isDark, list: true});
				
				style.backgroundColor = activeColorMap[5];
				if (isActive.value) {
					style.backgroundImage = `linear-gradient(to right, ${activeColorMap[5]}, ${activeColorMap[4]})`;	
					buttonState.status = 'open';
				} else {
					style.backgroundColor = inactiveColorMap[2];
					buttonState.status = 'close';
				}
				style.borderRadius = '42rpx';
				
				if (rootState.disabled) {
					style.opacity = 0.7;
				}
				
				return style;
			});
			
			const buttonStyle = computed(() => {
				const style: CSSProperties = reactive({});
				
				style.width = style.height = '26rpx';
				style.fontSize = 0;
				style.lineHeight = 1;
				style.backgroundColor = theme.colors[props.mode]['grey'][0];
				style.borderRadius = '26rpx';
				// style.transform = 'translateX(144%)';
				style.transition = 'transform 0.3s';
				
				return style;
			});
			
			let changeType = ''; // 标记开关状态更新类型
			
			const onClick = (e: Event) => {
				if (rootState.disabled || rootState.loading) {return false;}
				const value = isActive.value ? props.inactiveValue : props.activeValue;
				rootState.loading = true;
				changeType = 'click';
				emit('update:modelValue', value);
				emit('change', value, e);
			}
			
			watch(
				() => [props.disabled, props.loading, props.modelValue],
				(newVal) => {
					rootState.disabled = newVal[0];
					rootState.loading = newVal[1];
					
					if (changeType === 'click') {
						changeType = '';
					} else {
						emit('change', newVal[2]);
					}
					changeStatus()
				}
			);
			
			return {
				rootStyle,
				rootState,
				buttonStyle,
				buttonState,
				iconState,
				textState,
				onClick,
				isActive
			}
		}
	});
</script>

<style lang="less">
	.kui-switch {
		.open {
			transform: translateX(144%);
		}
		.close {
			transform: translateX(28%);
		}
		.open-text {
			transform: translateX(-120%);
		}
		.close-text {
			transform: translateX(120%);
		}
	}
</style>